package com.afinal.intelligencetrash.ui.fragment;

import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.afinal.intelligencetrash.Model.bean.TrashStatusDo;
import com.afinal.intelligencetrash.Model.remote.RTStutasRequester;
import com.afinal.intelligencetrash.R;
import com.afinal.intelligencetrash.ui.MapUtils.MapNaviListener;
import com.afinal.intelligencetrash.ui.MapUtils.MapNaviListenerWraper;
import com.afinal.intelligencetrash.ui.MapUtils.MarkerDo;
import com.afinal.intelligencetrash.ui.MapUtils.MarkerInfoWindowAdapter;
import com.afinal.intelligencetrash.ui.MapUtils.MarkerManager;
import com.afinal.intelligencetrash.ui.MapUtils.overlay.WalkRouteOverlay;
import com.afinal.intelligencetrash.ui.base.BaseFragment;
import com.afinal.intelligencetrash.ui.fragment.interfaces.FragmentView;
import com.afinal.intelligencetrash.utils.DebugLog;
import com.afinal.intelligencetrash.utils.LogUtil;
import com.afinal.intelligencetrash.utils.SimpleUtil;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.LocationSource;
import com.amap.api.maps.MapView;
import com.amap.api.maps.TextureMapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.navi.AMapNavi;
import com.amap.api.navi.AMapNaviListener;
import com.amap.api.navi.model.NaviLatLng;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch;

import com.amap.api.services.route.WalkPath;
import com.amap.api.services.route.WalkRouteResult;
import com.google.gson.Gson;

import java.util.List;


/**
 * Created by cyy on 17-10-12.
 */

public class TrashRTStatusTask extends BaseFragment
        implements FragmentView, AMapLocationListener, LocationSource, RouteSearch.OnRouteSearchListener,
        RTStutasRequester.RequestResultHandler{

    private static final String LOGTAG = LogUtil.makeLogTag(TrashRTStatusTask.class);
    private TextureMapView mapView;
    private AMap mMap;
    private MarkerManager markerManager;
    private RTStutasRequester rtStutasRequester;

    private RouteSearch mRouteSearch;
    private WalkRouteResult mWalkRouteResult;
    private WalkRouteOverlay walkRouteOverlay;

    public TrashRTStatusTask() {}

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        rtStutasRequester = new RTStutasRequester();
        rtStutasRequester.setResulthandler(this);
        mRouteSearch = new RouteSearch(getActivity());
        mRouteSearch.setRouteSearchListener(this);
    }

    @Override
    protected boolean initView(View rootView,@Nullable Bundle savedInstanceState) {
        if(mapView != null){
            return false;
        }
//        SimpleUtil.showToast(getActivity(), "TrashRTStatusTask:initView");

        mapView = (TextureMapView) rootView.findViewById(R.id.map);
        mapView.onCreate(savedInstanceState);
        mMap = mapView.getMap();
        initMapUI(mMap);
        initAMapLocation(mMap);
        initMarkerService(mMap);
        return true;
    }

    @Override
    protected void initData(@Nullable Bundle savedInstanceState) {
        /* List<MarkerDo> datelist = new ArrayList<>();
        datelist.add(new MarkerDo(11111L, 28.065114, 113.008596, "工科一楼", MarkerDo.STATE_NORMAL));
        datelist.add(new MarkerDo(22222L, 28.063590, 113.010441, "理科楼", MarkerDo.STATE_FULL));
        datelist.add(new MarkerDo(33333L, 28.066799, 113.010806, "图书馆", MarkerDo.STATE_NORMAL));
        datelist.add(new MarkerDo(44444L, 28.068844, 113.009701, "综教", MarkerDo.STATE_DANGER));
        markerManager.updateMarkers(datelist);*/
        rtStutasRequester.execute();
    }

    private void initAMapLocation(AMap mMap) {
        //设置定位源监听
        mMap.setLocationSource(this);
        // 是否可触发定位并显示定位层
        mMap.setMyLocationEnabled(true);
        // 设置定位的类型为定位模式.有定位、跟随或地图根据面向方向旋转几种
        mMap.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
    }

    private void initMapUI(AMap mMap) {
        //获取地图界面对象
        UiSettings mUiSetting = mMap.getUiSettings();
        // 是否显示定位按钮
        mUiSetting.setMyLocationButtonEnabled(true);
        //是否显示比例尺
        mUiSetting.setScaleControlsEnabled(true);
        //设置指南针
        mUiSetting.setCompassEnabled(true);

        //设置定位图标
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);//连续定位、蓝点不会移动到地图中心点，定位点依照设备方向旋转，并且蓝点会跟随设备移动。
        myLocationStyle.radiusFillColor(Color.argb(50,23,175,245));
        myLocationStyle.strokeColor(Color.argb(200,23,175,245));
        mMap.setMyLocationStyle(myLocationStyle);
    }

    private void initMarkerService(final AMap mMap){
        if(markerManager == null){
            markerManager = new MarkerManager(mMap);
        }
        MarkerInfoWindowAdapter adapter = new MarkerInfoWindowAdapter(getContext());
        adapter.setGoToHereOnClickLister(new MarkerInfoWindowAdapter.GoToHereOnClickLister() {
            @Override
            public void onClick(View v, Marker marker) {
                SimpleUtil.showToast(getActivity(), "开始路线规划");
                RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(currentPoint,
                                                                            new LatLonPoint(marker.getPosition().latitude,
                                                                                    marker.getPosition().longitude));
                RouteSearch.WalkRouteQuery query = new RouteSearch.WalkRouteQuery(fromAndTo);
                mRouteSearch.calculateWalkRouteAsyn(query);
            }
        });
        mMap.setInfoWindowAdapter(adapter);
        markerManager.setMarkerClickListener(new AMap.OnMarkerClickListener() {
            @Override
            public boolean onMarkerClick(Marker marker) {
                if(marker.isInfoWindowShown()){
                    marker.hideInfoWindow();
                }else {
                    marker.showInfoWindow();
                    markerManager.moveToMarker(marker);
                }
                return true;
            }
        });
        mMap.setOnInfoWindowClickListener(new AMap.OnInfoWindowClickListener() {
            @Override
            public void onInfoWindowClick(Marker marker) {
                marker.hideInfoWindow();
                walkRouteOverlay.removeFromMap();
            }
        });
    }

    @Override
    protected int getLayoutResId() {
        return R.layout.fragment_trasg_rt_status;
    }

    /*************************************************************************************************************/
    /*
    * AMapLocationListener
    * */
    private boolean isMoveCameraToLocation = false;
    private OnLocationChangedListener onLocationChangedListener = null;
    private LatLonPoint currentPoint;
    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if(aMapLocation != null && onLocationChangedListener != null){
            if (aMapLocation.getErrorCode() == 0){
                onLocationChangedListener.onLocationChanged(aMapLocation);
                if(isMoveCameraToLocation){
//                    Log.d(TAG, "onLocationChanged: 更新定位结果");
                    mMap.moveCamera(CameraUpdateFactory.zoomTo(16));
                    mMap.moveCamera(CameraUpdateFactory.changeLatLng(new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude())));
                    isMoveCameraToLocation = false;
                }
                if(currentPoint == null){
                    currentPoint = new LatLonPoint(aMapLocation.getLatitude(), aMapLocation.getLongitude());
                }
            }else {
                String errText = "定位失败," + aMapLocation.getErrorCode()+ ": " + aMapLocation.getErrorInfo();
                DebugLog.e(LOGTAG,"onLocationChanged:errText:"+errText);
            }
        }else {
            SimpleUtil.showToast(getActivity(), "网络错误");
        }
    }

    /*
    * LocationSource
    * */
    private AMapLocationClient locationClient = null;

    @Override
    public void activate(OnLocationChangedListener onLocationChangedListener) {
        DebugLog.d(LOGTAG, "activate: 开始定位");
        this.onLocationChangedListener = onLocationChangedListener;
        isMoveCameraToLocation = true;
        if (locationClient == null) {
            //初始化定位
            locationClient = new AMapLocationClient(getActivity());
            //初始化定位参数
            AMapLocationClientOption locationClientOption = new AMapLocationClientOption();
            //设置定位回调监听
            locationClient.setLocationListener(this);
            //设置为高精度定位模式
            locationClientOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            locationClientOption.setHttpTimeOut(30000);
            locationClientOption.setInterval(3000);
            //设置是否返回地址信息
            locationClientOption.setNeedAddress(true);
            //使用地图缓存
            locationClientOption.setLocationCacheEnable(true);
            //设置定位参数
            locationClient.setLocationOption(locationClientOption);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            locationClient.startLocation();//启动定位
        }
    }

    @Override
    public void deactivate() {
        DebugLog.d(DebugLog.MY_TAG, "deactivate: 停止定位!");
        onLocationChangedListener = null;
        if(locationClient != null){
            locationClient.stopLocation();
            locationClient.onDestroy();
        }
        locationClient = null;
    }

    /*************************************************************************************************************/

    @Override
    public void onResume() {
        super.onResume();
        mapView.onResume();
        locationClient.startLocation();
        rtStutasRequester.resume();
    }

    @Override
    public void onPause() {
        super.onPause();
        mapView.onPause();
        locationClient.stopLocation();
        rtStutasRequester.pause();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mapView.onLowMemory();
    }



    @Override
    protected void dealloc() {
        SimpleUtil.showToast(getActivity(), "dealloc");
        if(locationClient != null){
            locationClient.stopLocation();
            locationClient.onDestroy();
            locationClient = null;
        }
    }
    /****************************************************************************************************/
    /*
    * RTStutasRequester.RequestResultHandler
    * */
    @Override
    public void onRequestFinish(String statusCode, String result) {
        System.out.println("statusCode = "+statusCode+" result="+result);
        switch (statusCode){
            case RTStutasRequester.REQUEST_RESULT_SUCCESS:{
                Gson gson = SimpleUtil.getGsonInstance();
                TrashStatusDo r = gson.fromJson(result, TrashStatusDo.class);
                // 中南大学图书馆 112.944009,28.149714
                MarkerDo markerDo = new MarkerDo(28.149714, 112.944009, "图书馆");
                markerDo.setTrashStatusDo(r);
                markerManager.setMarker(markerDo);
            } break;
            default:{
                SimpleUtil.showToast(getActivity(), result);
            }
        }
    }
    /****************************************************************************************************/
    /*
    * RouteSearch.OnRouteSearchListener
    * */
    @Override
    public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {

    }

    @Override
    public void onDriveRouteSearched(DriveRouteResult driveRouteResult, int i) {

    }

    @Override
    public void onWalkRouteSearched(WalkRouteResult result, int errorCode) {
        if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getPaths() != null) {
                if (result.getPaths().size() > 0) {
                    mWalkRouteResult = result;
                    final WalkPath walkPath = mWalkRouteResult.getPaths()
                            .get(0);
                    if (walkRouteOverlay != null){
                        walkRouteOverlay.removeFromMap();
                    }
                    walkRouteOverlay = new WalkRouteOverlay(
                            getActivity(), mMap, walkPath,
                            mWalkRouteResult.getStartPos(),
                            mWalkRouteResult.getTargetPos());
                    walkRouteOverlay.addToMap();
                    walkRouteOverlay.zoomToSpan();

                    int dis = (int) walkPath.getDistance();
                    int dur = (int) walkPath.getDuration();

                } else if (result != null && result.getPaths() == null) {
                    SimpleUtil.showToast(getActivity(),getResources().getString(R.string.no_result));
                }
            } else {
                SimpleUtil.showToast(getActivity(), getResources().getString(R.string.unknown_error));
            }
        }
    }

    @Override
    public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {

    }



}
